﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Mongaba.Core;
using System.Threading;
using Mongaba.Core.DataContracts;
using Mongaba.Core.Factory;
using Mongaba.Core.ServiceContracts;
using System.IO;

namespace Mongaba
{
    internal partial class frmSession : Form
    {

        #region Static Members

        static Dictionary<string, frmSession> activeSessions = null;
        static Dictionary<string, frmSession> ActiveSessions
        {
            get {
                if (activeSessions == null)
                {
                    activeSessions = new Dictionary<string, frmSession>();
                }
                return activeSessions;
            }

        }
        internal static void DeliverMessage(MessageContract m)
        { 
            if(! ActiveSessions.ContainsKey(m.SenderId))
            {
                OpenSession(frmMainWindow.LocalProcess.getContract(), frmMainWindow.ProcessContractList[m.SenderId]);
            }
            ActiveSessions[m.SenderId].WriteMessage(m);
            ActiveSessions[m.SenderId].Show();
            ActiveSessions[m.SenderId].Activate();            
            
        }
        
        internal static void OpenSession(ProcessContract sender, ProcessContract receiver)
        {
            if (ActiveSessions.ContainsKey(receiver.Id))
            {
                ActiveSessions[receiver.Id].Show();
                ActiveSessions[receiver.Id].Activate();
            }
            else
            {
                frmSession newSession = new frmSession(sender, receiver);
                ActiveSessions.Add(receiver.Id, newSession);
                newSession.Show();
                newSession.Activate();
            }
        }     


        #endregion


        public frmSession(ProcessContract sender, ProcessContract receiver)
        {
            InitializeComponent();
            this.Icon = Properties.Resources.Mongaba;
            _localProcess = sender;
            _remoteProcess = receiver;           
            this.Text = String.Format("Mongaba - Conversando com {0}", receiver.User.Name);

        }


        #region Message


        ProcessContract _localProcess
        {
            get;
            set;
        }

        ProcessContract _remoteProcess
        {
            get;
            set;
        }

        void SendMessage(string message)
        {
            MessageContract mc = new MessageContract();
            mc.ReceiverId = _remoteProcess.Id;
            mc.SenderId = _localProcess.Id;
            mc.Body = message;
            mc.Date = DateTime.Now;
            txtWriter.Text = string.Empty;
            WriteMessage(mc);
            bgwSendMessage.RunWorkerAsync(mc);
        }

       
        void WriteMessage(MessageContract message)
        {
            ProcessContract p = null;
            if (message.SenderId == _localProcess.Id)
            {
                p = _localProcess;
            }
            else {
                p = _remoteProcess;
            }

            txtMessages.Text += String.Format("{0} - {1} Diz: {2}\r\n", message.Date.ToString("HH:mm:ss"), p.User.Name, message.Body);
            txtMessages.SelectionStart = txtMessages.Text.Length;
            txtMessages.ScrollToCaret();            
        }
        

        private void txtWriter_KeyPress(object sender, KeyPressEventArgs e)
        {
         
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (! String.IsNullOrEmpty(txtWriter.Text))
            { 
                SendMessage(txtWriter.Text);
            }
        }

        private void frmSession_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                this.Hide();
            }
        }

        private void txtWriter_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode ==  Keys.Enter)
            {
                if (txtWriter.Text.Length > 2)
                {
                    txtWriter.Text = txtWriter.Text.Substring(0, txtWriter.Text.Length - 2);
                    SendMessage(txtWriter.Text);
                }
                else
                {
                    txtWriter.Text = string.Empty;
                }
            }
        }

        private void frmSession_Shown(object sender, EventArgs e)
        {
            txtWriter.Focus();
        }

        private void tsmAbout_Click(object sender, EventArgs e)
        {
            new frmAboutBox().Show();
        }

        #endregion
        private void tsmSendFile_Click(object sender, EventArgs e)
        {
            ofdSender.ShowDialog();
        }

        void SendFile(string filePath,string fileName)
        {
            frmFileTransfer fl = new frmFileTransfer(FileTransferMode.Send, _remoteProcess);
            fl.SendFile(filePath,fileName);
        }

        private void frmSession_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.Copy;
            else
                e.Effect = DragDropEffects.None;

        }

        private void frmSession_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] filePaths = (string[])(e.Data.GetData(DataFormats.FileDrop));
                if (filePaths.Count() > 0)
                {
                    string filePath = filePaths.First();
                    FileInfo fl = new FileInfo(filePath);
                    SendFile(fl.FullName, fl.Name);
                }
            }
        }

        private void ofdSender_FileOk(object sender, CancelEventArgs e)
        {
            SendFile(ofdSender.FileName,ofdSender.SafeFileName);
        }

        private void bgwSendMessage_DoWork(object sender, DoWorkEventArgs e)
        {
             IMongabaProcess p = ProcessFactory.GetRemoteInstance(_remoteProcess.Address);
             MessageContract mc = e.Argument as MessageContract;
             p.ReceiveMessage(mc);
             ProcessFactory.RemoveRemoteInstanceConnection(_remoteProcess.Address);
            
        }

        private void bgwSendMessage_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                txtMessages.Text += String.Format("{0} - O usuário {1} desconectou-se.\r\n", DateTime.Now.ToString("HH:mm:ss"), _remoteProcess.User.Name);
                txtMessages.SelectionStart = txtMessages.Text.Length;
                txtMessages.ScrollToCaret();
                txtWriter.ReadOnly = true;
                ActiveSessions.Remove(_remoteProcess.Id);
            }
        }

        private void tsmCloseSession_Click(object sender, EventArgs e)
        {
            ActiveSessions.Remove(_remoteProcess.Id);
            this.Close();
        }

        
    }
}
